//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.ScientificWorkflow.UIDesigner
{
    using System;
    using System.IO;
    using System.Text;
    using System.Xml;
    using Microsoft.Research.ScientificWorkflow.TridentUtilities;

    /// <summary>
    /// A helper for the WFL file operations.
    /// </summary>
    public static class WflFileHelper
    {
        /// <summary>
        /// The workflow root node for the WFL file.
        /// </summary>
        public const string WorkflowRootNode = "Workflow";

        /// <summary>
        /// The workflow Id node tag for the WFL file.
        /// </summary>
        public const string WorkflowIdNode = "WorkflowId";

        /// <summary>
        /// The path of the wfl file.
        /// </summary>
        public const string WflFilePath = "LaunchWflPath";

        /// <summary>
        /// Saves as WFL the workflow represented by the passed guid.
        /// </summary>
        /// <param name="wfId">The wf id.</param>
        /// <returns>Save status.</returns>
        public static bool SaveAsWfl(Guid workflowId)
        {
            bool saveSuccess = true;
            System.Windows.Forms.SaveFileDialog saveDialog = new System.Windows.Forms.SaveFileDialog();

            // Filters the XOML file in the current Directory.
            saveDialog.Filter = "Wfl file (*.wfl)|*.wfl";

            // Make sure the dialog accepts only Filename supported by Win32.
            saveDialog.ValidateNames = true;

            // Restores the previous Directory the user had selected to Open/Save the file.
            saveDialog.RestoreDirectory = true;

            // Asks the User to create a new file if not present in the Directory.
            saveDialog.OverwritePrompt = true;

            string fileName = string.Empty;

            // Popup the save dialog untill users enter valid Name
            while (string.IsNullOrEmpty(fileName))
            {
                try
                {
                    System.Windows.Forms.DialogResult buttonClicked = saveDialog.ShowDialog();
                    if (buttonClicked == System.Windows.Forms.DialogResult.Cancel)
                    {
                        // Skip if user press cancel
                        return false;
                    }

                    fileName = saveDialog.FileName;
                }
                catch (PathTooLongException exception)
                {
                    saveDialog.FileName = string.Empty;
                    TridentMessageBox.ShowTridentErrorMessageBox(exception.Message);
                }
            }

            // Open the File Dialog Box.
            if (!string.IsNullOrEmpty(fileName))
            {
                StringBuilder errorBuilder = new StringBuilder(WorkflowApplicationResourceManager.GetString("WflFileError"));
                try
                {
                    XmlDocument xmlDocument = new XmlDocument();
                    XmlNode rootnode = xmlDocument.CreateNode(XmlNodeType.Element, WflFileHelper.WorkflowRootNode, string.Empty);
                    XmlElement childNode = xmlDocument.CreateElement(WflFileHelper.WorkflowIdNode);
                    childNode.InnerText = workflowId.ToString();
                    rootnode.AppendChild(childNode);
                    xmlDocument.AppendChild(rootnode);
                    using (FileStream fStream = new FileStream(fileName, FileMode.Create))
                    {
                        byte[] txtByte = System.Text.Encoding.Default.GetBytes(xmlDocument.OuterXml);
                        string txt64 = System.Convert.ToBase64String(txtByte);
                        using (BinaryWriter bWriter = new BinaryWriter(fStream))
                        {
                            bWriter.Write(txt64);
                        }
                    }
                }
                catch (XmlException ex)
                {
                    TridentErrorHandler.HandleUIException(ex);
                    TridentMessageBox.ShowTridentErrorMessageBox(errorBuilder.Append(ex.Message).ToString());
                    saveSuccess = false;
                }
                catch (IOException ex)
                {
                    TridentErrorHandler.HandleUIException(ex);
                    TridentMessageBox.ShowTridentErrorMessageBox(errorBuilder.Append(ex.Message).ToString());
                    saveSuccess = false;
                }
                catch (Exception ex)
                {
                    TridentErrorHandler.HandleUIException(ex);
                    TridentMessageBox.ShowTridentErrorMessageBox(errorBuilder.Append(ex.Message).ToString());
                    saveSuccess = false;
                }
            }

            return saveSuccess;
        }
    }
}
